<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
    

<head><meta name="generator" content="Hexo 3.8.0">
    <meta charset="utf-8">
    <meta name="keywords" content="web自动化测试, Zhou•Yong">
    <meta name="description" content="自动化测试 web自动化测试只适用于需求变动不频繁，项目周期长，项目需要回归 Web自动化测试属于黑盒测试(功能测试)
Selenium+Python1. Python 开发环境
2. 安装selenium包
3. 安装浏览器
4. 安装浏">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <title>web自动化测试 | Zhou•Yong</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/css/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery-2.2.0.min.js"></script>
<link rel="stylesheet" href="/css/prism-tomorrow.css" type="text/css"></head>

</head>

<body>

<header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="container">
            <div class="nav-wrapper">
                <div class="brand-logo">
                    <a href="/" class="waves-effect waves-light">
                        
                        <img src="/medias/logo.png" class="logo-img hide-on-small-only">
                        
                        <span class="logo-span">Zhou•Yong</span>
                    </a>
                </div>
                <a href="#" data-activates="mobile-nav" class="button-collapse"><i class="fa fa-navicon"></i></a>
<ul class="right">
    
    <li class="hide-on-med-and-down">
        <a href="/" class="waves-effect waves-light">
            
            <i class="fa fa-home"></i>
            
            <span>主页</span>
        </a>
    </li>
    
    <li class="hide-on-med-and-down">
        <a href="/about" class="waves-effect waves-light">
            
            <i class="fa fa-user-circle-o"></i>
            
            <span>个人介绍</span>
        </a>
    </li>
    
    <li class="hide-on-med-and-down">
        <a href="/categories" class="waves-effect waves-light">
            
            <i class="fa fa-bookmark"></i>
            
            <span>分类</span>
        </a>
    </li>
    
    <li class="hide-on-med-and-down">
        <a href="/tags" class="waves-effect waves-light">
            
            <i class="fa fa-tags"></i>
            
            <span>标签</span>
        </a>
    </li>
    
    <li class="hide-on-med-and-down">
        <a href="/friends" class="waves-effect waves-light">
            
            <i class="fa fa-address-book"></i>
            
            <span>推荐</span>
        </a>
    </li>
    
    <li>
        <a id="toggleSearch" class="waves-effect waves-light">
            <i id="searchIcon" class="mdi-action-search"></i>
        </a>
    </li>

</ul>

<div class="side-nav" id="mobile-nav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">Zhou•Yong</div>
        <div class="logo-desc">
            
            你迈出的步伐不非得很大，只要你是在正确的方向前进就行
            
        </div>
    </div>

    <ul class="menu-list mobile-menu-list">
        
        <li>
            <a href="/" class="waves-effect waves-light">
                
                <i class="fa fa-fw fa-home"></i>
                
                主页
            </a>
        </li>
        
        <li>
            <a href="/about" class="waves-effect waves-light">
                
                <i class="fa fa-fw fa-user-circle-o"></i>
                
                个人介绍
            </a>
        </li>
        
        <li>
            <a href="/categories" class="waves-effect waves-light">
                
                <i class="fa fa-fw fa-bookmark"></i>
                
                分类
            </a>
        </li>
        
        <li>
            <a href="/tags" class="waves-effect waves-light">
                
                <i class="fa fa-fw fa-tags"></i>
                
                标签
            </a>
        </li>
        
        <li>
            <a href="/friends" class="waves-effect waves-light">
                
                <i class="fa fa-fw fa-address-book"></i>
                
                推荐
            </a>
        </li>
        
        
    </ul>

    <div class="social-link"><a href="#!" class="tooltipped" data-tooltip="邮件联系我: zy20081@126.com" data-position="top" data-delay="50">
    <i class="fa fa-envelope-open"></i>
</a>
<a href="#!" class="tooltipped" data-tooltip="QQ联系我: 314153271" data-position="top" data-delay="50">
    <i class="fa fa-qq"></i>
</a>

<a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
    <i class="fa fa-rss"></i>
</a>
</div>
</div>

            </div>
        </div>

        
    </nav>
</header>





<div class="bg-cover post-cover" style="background-image: url('/medias/featureimages/22.jpg')">
    <div class="container">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <div class="description center-align post-title">
                        web自动化测试
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>



<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1,
    #articleContent h2,
    #articleContent h3,
    #articleContent h4,
    #articleContent h5,
    #articleContent h6 {
        padding-top: 76px;
        margin-top: -76px;
    }

    #articleContent h1 {
        line-height: 3.5rem;
    }

    #articleContent h2 {
        line-height: 3.2rem;
    }

    #articleContent h3 {
        line-height: 2.8rem;
    }

    #articleContent h4 {
        line-height: 2.5rem;
    }

    #articleContent h5 {
        line-height: 2.2rem;
    }

    #articleContent h6 {
        line-height: 1.9rem;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        margin: 35px 0 15px 0;
        padding-left: 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #toc-content .is-active-link::before {
        background-color: #42b983;
    }
</style>
<div class="row">
    <div class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            
            <div class="article-tag">
                
                <a href="/tags/web自动化测试/" target="_blank">
                    <span class="chip bg-color">web自动化测试</span>
                </a>
                
            </div>
            
            <div class="post-info">
                
                <span class="post-cate">
                    <i class="fa fa-bookmark fa-fw icon-category"></i>
                    
                    <a href="/categories/测试/" class="post-category" target="_blank">
                        测试
                    </a>
                    
                </span>
                

                <span class="post-date">
                    <i class="fa fa-clock-o fa-fw"></i>2020-10-08
                </span>
            </div>
        </div>
        <hr>
        <div class="card-content article-card-content">
            <div id="articleContent">
                <h2 id="自动化测试"><a href="#自动化测试" class="headerlink" title="自动化测试"></a>自动化测试</h2><p> web自动化测试只适用于需求变动不频繁，项目周期长，项目需要回归<br> Web自动化测试属于黑盒测试(功能测试)</p>
<h2 id="Selenium-Python"><a href="#Selenium-Python" class="headerlink" title="Selenium+Python"></a>Selenium+Python</h2><pre class=" language-bash"><code class="language-bash">1. Python 开发环境
2. 安装selenium包
3. 安装浏览器
4. 安装浏览器驱动
</code></pre>
<h2 id="安装selenium包"><a href="#安装selenium包" class="headerlink" title="安装selenium包"></a>安装selenium包</h2><pre class=" language-bash"><code class="language-bash">PIP工具
pip是一个通用的 Python 包管理工具，提供了对 Python 包的查找、下载、安装、卸载的功能。
安装
pip <span class="token function">install</span> selenium
卸载
pip uninstall selenium
查看
pip show selenium
</code></pre>
<h2 id="安装浏览器驱动"><a href="#安装浏览器驱动" class="headerlink" title="安装浏览器驱动"></a>安装浏览器驱动</h2><pre class=" language-bash"><code class="language-bash">火狐浏览器
1. Firefox 48 以上版本
selenium 3.x + Firefox驱动<span class="token punctuation">(</span>geckodriver<span class="token punctuation">)</span>
驱动下载地址：https://github.com/mozilla/geckodriver/releases
2. Firefox 48 以下版本
selenium 2.x + 内置驱动

谷歌浏览器
selenium 2.x/3.x + Chrome驱动<span class="token punctuation">(</span>chromedriver<span class="token punctuation">)</span>
驱动下载地址：https://sites.google.com/a/chromium.org/chromedriver/downloads

</code></pre>
<h2 id="测试环境"><a href="#测试环境" class="headerlink" title="测试环境"></a>测试环境</h2><pre class=" language-bash"><code class="language-bash">1. 导包
from selenium <span class="token function">import</span> webdriver
2. 创建浏览器驱动对象
Firefox浏览器：driver <span class="token operator">=</span> webdriver.Firefox<span class="token punctuation">(</span><span class="token punctuation">)</span>
Chrome浏览器：driver <span class="token operator">=</span> webdriver.Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span>
Edge浏览器：driver <span class="token operator">=</span> webdriver.Edge<span class="token punctuation">(</span><span class="token punctuation">)</span>
3. 打开Web页面
driver.get<span class="token punctuation">(</span><span class="token string">"http://www.baidu.com/"</span><span class="token punctuation">)</span>
4. 暂停
time.sleep<span class="token punctuation">(</span>3<span class="token punctuation">)</span>
5. 关闭驱动对象
driver.quit<span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre>
<h2 id="自动化测试结构"><a href="#自动化测试结构" class="headerlink" title="自动化测试结构"></a>自动化测试结构</h2><pre class=" language-bash"><code class="language-bash">1. base（基类）
2. page（页面对象）
3. scripts（业务脚本）
4. tool（工具类）
5. data（存储测试数据文件）
6. log（日志）
7. image（失败截图）
8. report（测试报告）
</code></pre>
<h3 id="base（基类）"><a href="#base（基类）" class="headerlink" title="base（基类）"></a>base（基类）</h3><h4 id="base-py"><a href="#base-py" class="headerlink" title="base.py"></a>base.py</h4><pre class=" language-bash"><code class="language-bash"><span class="token function">import</span> <span class="token function">time</span>
from selenium.webdriver.support.wait <span class="token function">import</span> WebDriverWait
class Base:

    def __init__<span class="token punctuation">(</span>self, driver<span class="token punctuation">)</span>:
        self.driver <span class="token operator">=</span> driver

    <span class="token comment" spellcheck="true"># 查找元素方法 封装</span>
    def base_find<span class="token punctuation">(</span>self, loc,  timeout<span class="token operator">=</span>30, poll<span class="token operator">=</span>0.5<span class="token punctuation">)</span>:
        <span class="token comment" spellcheck="true"># 使用显示等待 查找元素</span>
        <span class="token keyword">return</span> WebDriverWait<span class="token punctuation">(</span>self.driver,
                             timeout<span class="token operator">=</span>timeout,
                             poll_frequency<span class="token operator">=</span>poll<span class="token punctuation">)</span>.until<span class="token punctuation">(</span>lambda x:x.find_element<span class="token punctuation">(</span>*loc<span class="token punctuation">))</span>

    <span class="token comment" spellcheck="true"># 点击元素 方法封装</span>
    def base_click<span class="token punctuation">(</span>self, loc<span class="token punctuation">)</span>:
        self.base_find<span class="token punctuation">(</span>loc<span class="token punctuation">)</span>.click<span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 输入元素 方法封装</span>
    def base_input<span class="token punctuation">(</span>self, loc, value<span class="token punctuation">)</span>:
        <span class="token comment" spellcheck="true"># 获取元素</span>
        el <span class="token operator">=</span> self.base_find<span class="token punctuation">(</span>loc<span class="token punctuation">)</span>
        <span class="token comment" spellcheck="true"># 清空</span>
        el.clear<span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token comment" spellcheck="true"># 输入</span>
        el.send_keys<span class="token punctuation">(</span>value<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 获取文本信息 方法封装</span>
    def base_get_text<span class="token punctuation">(</span>self, loc<span class="token punctuation">)</span>:
        <span class="token keyword">return</span> self.base_find<span class="token punctuation">(</span>loc<span class="token punctuation">)</span>.text

    <span class="token comment" spellcheck="true"># 截图 方法封装</span>
    def base_get_image<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        self.driver.get_screenshot_as_file<span class="token punctuation">(</span><span class="token string">"../image/{}.png"</span>.format<span class="token punctuation">(</span>time.strftime<span class="token punctuation">(</span><span class="token string">"%Y_%m_%d %H_%M_%S"</span><span class="token punctuation">))</span><span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 判断元素是否存在 方法封装</span>
    def base_element_is_exist<span class="token punctuation">(</span>self, loc<span class="token punctuation">)</span>:
        try:
            self.base_find<span class="token punctuation">(</span>loc, timeout<span class="token operator">=</span>2<span class="token punctuation">)</span>
            <span class="token keyword">return</span> True <span class="token comment" spellcheck="true"># 代表元素存在</span>
        except:
            <span class="token keyword">return</span> False <span class="token comment" spellcheck="true"># 代表元素不存在</span>
</code></pre>
<h4 id="get-driver-py"><a href="#get-driver-py" class="headerlink" title="get_driver.py"></a>get_driver.py</h4><pre class=" language-bash"><code class="language-bash">from selenium <span class="token function">import</span> webdriver
<span class="token function">import</span> page


class GetDriver:
    <span class="token comment" spellcheck="true"># 设置类属性</span>
    driver <span class="token operator">=</span> None

    <span class="token comment" spellcheck="true"># 获取driver</span>
    @classmethod
    def get_driver<span class="token punctuation">(</span>cls<span class="token punctuation">)</span>:
        <span class="token keyword">if</span> cls.driver is None:
            <span class="token comment" spellcheck="true"># 实例化浏览器</span>
            cls.driver <span class="token operator">=</span> webdriver.Firefox<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 最大化</span>
            cls.driver.maximize_window<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 打开浏览器</span>
            cls.driver.get<span class="token punctuation">(</span>page.url<span class="token punctuation">)</span>
        <span class="token keyword">return</span> cls.driver

    <span class="token comment" spellcheck="true"># 退出driver</span>
    @classmethod
    def quit_driver<span class="token punctuation">(</span>cls<span class="token punctuation">)</span>:
        <span class="token keyword">if</span> cls.driver:
            print<span class="token punctuation">(</span><span class="token string">"关闭之前："</span>, cls.driver<span class="token punctuation">)</span>
            cls.driver.quit<span class="token punctuation">(</span><span class="token punctuation">)</span>
            print<span class="token punctuation">(</span><span class="token string">"关闭之后："</span>, cls.driver<span class="token punctuation">)</span>

            <span class="token comment" spellcheck="true"># 注意：此处有一个很大坑</span>
            cls.driver <span class="token operator">=</span> None
            <span class="token comment" spellcheck="true"># print("置空之后：", cls.driver)</span>


<span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token keyword">:</span>
    <span class="token comment" spellcheck="true"># 第一次获取浏览器</span>
    print<span class="token punctuation">(</span>GetDriver<span class="token punctuation">(</span><span class="token punctuation">)</span>.get_driver<span class="token punctuation">(</span><span class="token punctuation">))</span>
    <span class="token comment" spellcheck="true"># 第二次获取浏览器</span>
    print<span class="token punctuation">(</span>GetDriver<span class="token punctuation">(</span><span class="token punctuation">)</span>.get_driver<span class="token punctuation">(</span><span class="token punctuation">))</span>
    <span class="token comment" spellcheck="true"># 调用关闭，测试 关闭后driver是否为None</span>
    GetDriver<span class="token punctuation">(</span><span class="token punctuation">)</span>.quit_driver<span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token comment" spellcheck="true"># print(GetDriver().get_driver())</span>

</code></pre>
<h3 id="page（页面对象）"><a href="#page（页面对象）" class="headerlink" title="page（页面对象）"></a>page（页面对象）</h3><h4 id="init-py"><a href="#init-py" class="headerlink" title="init.py"></a><strong>init</strong>.py</h4><pre class=" language-bash"><code class="language-bash">from selenium.webdriver.common.by <span class="token function">import</span> By
<span class="token string">""</span><span class="token string">"项目配置地址"</span><span class="token string">""</span>
url <span class="token operator">=</span> <span class="token string">"http://localhost"</span>


<span class="token string">""</span><span class="token string">"以下为登录页面元素配置信息"</span><span class="token string">""</span>
<span class="token comment" spellcheck="true"># 登录链接</span>
login_link <span class="token operator">=</span> By.PARTIAL_LINK_TEXT, <span class="token string">"登录"</span>
<span class="token comment" spellcheck="true"># 用户名</span>
login_username <span class="token operator">=</span> By.ID, <span class="token string">"username"</span>
<span class="token comment" spellcheck="true"># 密码</span>
login_pwd <span class="token operator">=</span> By.ID, <span class="token string">"password"</span>
<span class="token comment" spellcheck="true"># 验证码</span>
login_verify_code <span class="token operator">=</span> By.ID, <span class="token string">"verify_code"</span>
<span class="token comment" spellcheck="true"># 登录按钮</span>
login_btn <span class="token operator">=</span> By.CSS_SELECTOR, <span class="token string">".J-login-submit"</span>
<span class="token comment" spellcheck="true"># 获取异常文本信息</span>
login_err_info <span class="token operator">=</span> By.CSS_SELECTOR, <span class="token string">".layui-layer-content"</span>
<span class="token comment" spellcheck="true"># 点击异常提示框 按钮</span>
login_err_btn_ok <span class="token operator">=</span> By.CSS_SELECTOR, <span class="token string">".layui-layer-btn0"</span>
<span class="token comment" spellcheck="true"># 安全退出</span>
login_logout <span class="token operator">=</span> By.PARTIAL_LINK_TEXT, <span class="token string">"安全退出"</span>

<span class="token string">""</span><span class="token string">"以下为订单页面配置数据"</span><span class="token string">""</span>
</code></pre>
<h4 id="page-login-py"><a href="#page-login-py" class="headerlink" title="page_login.py"></a>page_login.py</h4><pre class=" language-bash"><code class="language-bash"><span class="token function">import</span> page
from base.base <span class="token function">import</span> Base


class PageLogin<span class="token punctuation">(</span>Base<span class="token punctuation">)</span>:
    <span class="token comment" spellcheck="true"># 点击登录链接</span>
    def page_click_login_link<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        self.base_click<span class="token punctuation">(</span>page.login_link<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 输入用户名</span>
    def page_input_username<span class="token punctuation">(</span>self, username<span class="token punctuation">)</span>:
        self.base_input<span class="token punctuation">(</span>page.login_username, username<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 输入密码</span>
    def page_input_password<span class="token punctuation">(</span>self, pwd<span class="token punctuation">)</span>:
        self.base_input<span class="token punctuation">(</span>page.login_pwd, pwd<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 输入验证</span>
    def page_input_verify_code<span class="token punctuation">(</span>self, code<span class="token punctuation">)</span>:
        self.base_input<span class="token punctuation">(</span>page.login_verify_code, code<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 点击登录按钮</span>
    def page_click_login_btn<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        self.base_click<span class="token punctuation">(</span>page.login_btn<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 获取异常提示信息</span>
    def page_get_error_info<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        <span class="token keyword">return</span> self.base_get_text<span class="token punctuation">(</span>page.login_err_info<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 点击异常信息框 确定</span>
    def page_click_err_btn_ok<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        self.base_click<span class="token punctuation">(</span>page.login_err_btn_ok<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 截图</span>
    def page_get_img<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        self.base_get_image<span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 点击 安全退出 --》退出使用</span>
    def page_click_logout<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        self.base_click<span class="token punctuation">(</span>page.login_logout<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 判断是否登录成功</span>
    def page_is_login_success<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        <span class="token keyword">return</span> self.base_if_exist<span class="token punctuation">(</span>page.login_logout<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 判断是否退出成功</span>
    def page_is_logout_success<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
        <span class="token keyword">return</span> self.base_if_exist<span class="token punctuation">(</span>page.login_link<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 组合业务方法</span>
    def page_login<span class="token punctuation">(</span>self, username, pwd, code<span class="token punctuation">)</span>:
        self.page_input_username<span class="token punctuation">(</span>username<span class="token punctuation">)</span>
        self.page_input_password<span class="token punctuation">(</span>pwd<span class="token punctuation">)</span>
        self.page_input_verify_code<span class="token punctuation">(</span>code<span class="token punctuation">)</span>
        self.page_click_login_btn<span class="token punctuation">(</span><span class="token punctuation">)</span>

</code></pre>
<h3 id="scripts（业务脚本）"><a href="#scripts（业务脚本）" class="headerlink" title="scripts（业务脚本）"></a>scripts（业务脚本）</h3><h4 id="test-login-py"><a href="#test-login-py" class="headerlink" title="test_login.py"></a>test_login.py</h4><pre class=" language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 导包</span>
<span class="token function">import</span> unittest
from <span class="token function">time</span> <span class="token function">import</span> <span class="token function">sleep</span>

from base.get_driver <span class="token function">import</span> GetDriver
from page.page_login <span class="token function">import</span> PageLogin
from parameterized <span class="token function">import</span> parameterized

from tool.read_json <span class="token function">import</span> read_json


def get_data<span class="token punctuation">(</span><span class="token punctuation">)</span>:
    arrs <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> data <span class="token keyword">in</span> read_json<span class="token punctuation">(</span><span class="token string">"login.json"</span><span class="token punctuation">)</span>.values<span class="token punctuation">(</span><span class="token punctuation">)</span>:
        arrs.append<span class="token punctuation">((</span>data.get<span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"password"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"verify_code"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"expect_result"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"success"</span><span class="token punctuation">))</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> arrs <span class="token comment" spellcheck="true"># 注意：必须进行return 返回</span>


<span class="token comment" spellcheck="true"># 新建测试类 并 继承</span>
class TestLogin<span class="token punctuation">(</span>unittest.TestCase<span class="token punctuation">)</span>:
    login <span class="token operator">=</span> None
    <span class="token comment" spellcheck="true"># setUp</span>

    @classmethod
    def setUpClass<span class="token punctuation">(</span>cls<span class="token punctuation">)</span>:
        <span class="token comment" spellcheck="true"># 实例化 获取页面对象 PageLogin</span>
        cls.login <span class="token operator">=</span> PageLogin<span class="token punctuation">(</span>GetDriver<span class="token punctuation">(</span><span class="token punctuation">)</span>.get_driver<span class="token punctuation">(</span><span class="token punctuation">))</span>
        <span class="token comment" spellcheck="true"># 点击登录连接</span>
        cls.login.page_click_login_link<span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># tearDown</span>
    @classmethod
    def tearDownClass<span class="token punctuation">(</span>cls<span class="token punctuation">)</span>:
        sleep<span class="token punctuation">(</span>3<span class="token punctuation">)</span>
        <span class="token comment" spellcheck="true"># 关闭 driver驱动对象</span>
        GetDriver<span class="token punctuation">(</span><span class="token punctuation">)</span>.quit_driver<span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 登录测试方法</span>
    @parameterized.expand<span class="token punctuation">(</span>get_data<span class="token punctuation">(</span><span class="token punctuation">))</span>
    def test_login<span class="token punctuation">(</span>self, username, pwd, code, expect_result, success<span class="token punctuation">)</span>:
        <span class="token comment" spellcheck="true"># 调用登录方法</span>
        self.login.page_login<span class="token punctuation">(</span>username, pwd, code<span class="token punctuation">)</span>
        <span class="token keyword">if</span> success:
            try:
                <span class="token comment" spellcheck="true"># 判断安全退出是否存在</span>
                self.assertTrue<span class="token punctuation">(</span>self.login.page_is_login_success<span class="token punctuation">(</span><span class="token punctuation">))</span>
                <span class="token comment" spellcheck="true"># 点击退出</span>
                self.login.page_click_logout<span class="token punctuation">(</span><span class="token punctuation">)</span>
                try:
                    self.assertTrue<span class="token punctuation">(</span>self.login.page_is_logout_success<span class="token punctuation">)</span>
                except:
                    <span class="token comment" spellcheck="true"># 截图</span>
                    self.login.page_get_img<span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token comment" spellcheck="true"># 点击登录连接</span>
                self.login.page_click_login_link<span class="token punctuation">(</span><span class="token punctuation">)</span>
            except:
                <span class="token comment" spellcheck="true"># 截图</span>
                self.login.page_get_img<span class="token punctuation">(</span><span class="token punctuation">)</span>
        else:
            <span class="token comment" spellcheck="true"># 获取登录提示信息</span>
            msg <span class="token operator">=</span> self.login.page_get_error_info<span class="token punctuation">(</span><span class="token punctuation">)</span>
            try:
                <span class="token comment" spellcheck="true"># 断言</span>
                self.assertEqual<span class="token punctuation">(</span>msg, expect_result<span class="token punctuation">)</span>

            except AssertionError:
                <span class="token comment" spellcheck="true"># 截图</span>
                self.login.page_get_img<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 点击 确认框</span>
            self.login.page_click_err_btn_ok<span class="token punctuation">(</span><span class="token punctuation">)</span>

</code></pre>
<h3 id="tool（工具类）"><a href="#tool（工具类）" class="headerlink" title="tool（工具类）"></a>tool（工具类）</h3><h4 id="read-json-py"><a href="#read-json-py" class="headerlink" title="read_json.py"></a>read_json.py</h4><pre class=" language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 导包</span>
<span class="token function">import</span> json


def read_json<span class="token punctuation">(</span>filename<span class="token punctuation">)</span>:
    filepath <span class="token operator">=</span> <span class="token string">"../data/"</span> + filename
    <span class="token comment" spellcheck="true"># 打开文件并调用 load方法</span>
    with open<span class="token punctuation">(</span>filepath, <span class="token string">"r"</span>, encoding<span class="token operator">=</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span>as f:
        <span class="token keyword">return</span> json.load<span class="token punctuation">(</span>f<span class="token punctuation">)</span>

<span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token keyword">:</span>
    print<span class="token punctuation">(</span>read_json<span class="token punctuation">(</span><span class="token string">"login.json"</span><span class="token punctuation">))</span>
    <span class="token string">""</span><span class="token string">"
        需求格式：[(),(),(),(),(),()]
        实际格式为：{"</span>login_001<span class="token string">":{}}
    "</span><span class="token string">""</span>
    print<span class="token punctuation">(</span><span class="token string">"--"</span> * 50<span class="token punctuation">)</span>

    <span class="token comment" spellcheck="true"># 定义空列表</span>
    arrs <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> data <span class="token keyword">in</span> read_json<span class="token punctuation">(</span><span class="token string">"login.json"</span><span class="token punctuation">)</span>.values<span class="token punctuation">(</span><span class="token punctuation">)</span>:
        arrs.append<span class="token punctuation">((</span>data.get<span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"password"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"verify_code"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"expect_result"</span><span class="token punctuation">)</span>,
                     data.get<span class="token punctuation">(</span><span class="token string">"success"</span><span class="token punctuation">))</span><span class="token punctuation">)</span>
    print<span class="token punctuation">(</span>arrs<span class="token punctuation">)</span>

</code></pre>
<h4 id="read-txt-py"><a href="#read-txt-py" class="headerlink" title="read_txt.py"></a>read_txt.py</h4><pre class=" language-bash"><code class="language-bash">def read_txt<span class="token punctuation">(</span>filename<span class="token punctuation">)</span>:
    filepath <span class="token operator">=</span> <span class="token string">"../data/"</span>+ filename
    with open<span class="token punctuation">(</span>filepath, <span class="token string">"r"</span>, encoding<span class="token operator">=</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span>as f:
        <span class="token keyword">return</span> f.readlines<span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token keyword">:</span>
    <span class="token comment" spellcheck="true"># datas = read_txt("login.txt")</span>
    <span class="token comment" spellcheck="true"># arrs = []</span>
    <span class="token comment" spellcheck="true"># for data in datas:</span>
    <span class="token comment" spellcheck="true">#     arrs.append(tuple(data.strip().split(",")))</span>
    <span class="token comment" spellcheck="true"># print(arrs)</span>


    <span class="token comment" spellcheck="true"># 写法：</span>
    arrs <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> data <span class="token keyword">in</span> read_txt<span class="token punctuation">(</span><span class="token string">"login.txt"</span><span class="token punctuation">)</span>:
        arrs.append<span class="token punctuation">(</span>tuple<span class="token punctuation">(</span>data.strip<span class="token punctuation">(</span><span class="token punctuation">)</span>.split<span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">))</span><span class="token punctuation">)</span>
    print<span class="token punctuation">(</span>arrs<span class="token punctuation">)</span>

    <span class="token string">""</span><span class="token string">"
        难点：
            1. 去除字符串前后空格、换行符  strip()
            2. 使用split("</span>,<span class="token string">")拆分字符串，结果返回列表
            3. 使用tuple()将返回的列表强转为元祖
    "</span><span class="token string">""</span>

</code></pre>
<h4 id="get-log-py"><a href="#get-log-py" class="headerlink" title="get_log.py"></a>get_log.py</h4><pre class=" language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 导包</span>
<span class="token function">import</span> logging.handlers


class GetLogger:
    logger <span class="token operator">=</span> None

    @classmethod
    def get_logger<span class="token punctuation">(</span>cls<span class="token punctuation">)</span>:
        <span class="token keyword">if</span> cls.logger is None:
            <span class="token comment" spellcheck="true"># 获取 日志器</span>
            cls.logger <span class="token operator">=</span> logging.getLogger<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 设置 日志器 级别</span>
            cls.logger.setLevel<span class="token punctuation">(</span>logging.INFO<span class="token punctuation">)</span>

            <span class="token comment" spellcheck="true"># 获取处理器 控制台</span>
            sh <span class="token operator">=</span> logging.StreamHandler<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 获取处理器 文件-以时间分隔</span>
            th <span class="token operator">=</span> logging.handlers.TimedRotatingFileHandler<span class="token punctuation">(</span>filename<span class="token operator">=</span><span class="token string">"../log/log02.log"</span>,
                                                           when<span class="token operator">=</span><span class="token string">"midnight"</span>,
                                                           interval<span class="token operator">=</span>1,
                                                           backupCount<span class="token operator">=</span>30,
                                                           encoding<span class="token operator">=</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 设置格式器</span>
            <span class="token function">fmt</span> <span class="token operator">=</span> <span class="token string">"%(asctime)s %(levelname)s [%(name)s] [%(filename)s (%(funcName)s:%(lineno)d] - %(message)s"</span>
            fm <span class="token operator">=</span> logging.Formatter<span class="token punctuation">(</span>fmt<span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 将格式器添加到 处理器 控制台  </span>
            sh.setFormatter<span class="token punctuation">(</span>fm<span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 将格式器添加到 处理器 文件</span>
            th.setFormatter<span class="token punctuation">(</span>fm<span class="token punctuation">)</span>
            <span class="token comment" spellcheck="true"># 将处理器添加到 日志器</span>
            cls.logger.addHandler<span class="token punctuation">(</span>sh<span class="token punctuation">)</span>
            cls.logger.addHandler<span class="token punctuation">(</span>th<span class="token punctuation">)</span>
        <span class="token keyword">return</span> cls.logger


<span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token keyword">:</span>
    logger <span class="token operator">=</span> GetLogger<span class="token punctuation">(</span><span class="token punctuation">)</span>.get_logger<span class="token punctuation">(</span><span class="token punctuation">)</span>
    logger.info<span class="token punctuation">(</span><span class="token string">"info信息被执行"</span><span class="token punctuation">)</span>
    logger.error<span class="token punctuation">(</span><span class="token string">"error信息被执行"</span><span class="token punctuation">)</span>
</code></pre>
<h3 id="report（测试报告）"><a href="#report（测试报告）" class="headerlink" title="report（测试报告）"></a>report（测试报告）</h3><pre class=" language-bash"><code class="language-bash">run_main_html.py 放在tools下
这里使用的三方的HTMLTestRunner.py 进行测试报告的导出
<span class="token string">""</span><span class="token string">"
    目标：基于unittest框架执行生成html版报告
    操作：
        1. 复制HtmlTestRunner.py文件到指定目录
        2. 导包 from HTMLTestRunner import HTMLTestRunner
        3. 获取报告存放文件流，并实例化HTMLTestRunner类，执行run方法
"</span><span class="token string">""</span>
<span class="token comment" spellcheck="true"># 导包</span>
<span class="token function">import</span> unittest

<span class="token function">import</span> <span class="token function">time</span>

from tools.HTMLTestRunner <span class="token function">import</span> HTMLTestRunner

<span class="token comment" spellcheck="true"># 定义 测试套件</span>
suite <span class="token operator">=</span> unittest.defaultTestLoader.discover<span class="token punctuation">(</span><span class="token string">"../case"</span>, pattern<span class="token operator">=</span><span class="token string">"test*.py"</span><span class="token punctuation">)</span>
<span class="token comment" spellcheck="true"># 定义报告存放路径及文件名称</span>
report_dir <span class="token operator">=</span> <span class="token string">"../report/{}.html"</span>.format<span class="token punctuation">(</span>time.strftime<span class="token punctuation">(</span><span class="token string">"%Y_%m_%d %H_%M_%S"</span><span class="token punctuation">))</span>
<span class="token comment" spellcheck="true"># 获取报告文件流 并执行</span>
with open<span class="token punctuation">(</span>report_dir, <span class="token string">"wb"</span><span class="token punctuation">)</span> as f:
    HTMLTestRunner<span class="token punctuation">(</span>stream<span class="token operator">=</span>f,
                   title<span class="token operator">=</span><span class="token string">"XX项目自动化测试报告"</span>,
                   description<span class="token operator">=</span><span class="token string">"操作系统 win7"</span><span class="token punctuation">)</span>.run<span class="token punctuation">(</span>suite<span class="token punctuation">)</span>

</code></pre>
<p><img src="/2020/10/08/web-zi-dong-hua-ce-shi/1.jpg" alt="图1"></p>

            </div>
            <hr>

            
            <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.88rem;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff;
        background-color: #22AB38;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff;
        background-color: #019FE8;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a class="reward-link btn-floating btn-large waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close"><i class="fa fa-close"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs">
                        <li class="tab wechat-tab waves-effect waves-light"><a class="active" href="#wechat">微信</a></li>
                        <li class="tab alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                    </ul>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('#reward .reward-link').on('click', function () {
            $('#rewardModal').openModal();
        });

        $('#rewardModal .close').on('click', function () {
            $('#rewardModal').closeModal();
        });
    });
</script>
            

            <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">

<div id="article-share">
    
    <div class="social-share" data-disabled="qzone" data-wechat-qrcode-helper="<p>微信里点“发现”->“扫一扫”二维码便可查看分享。</p>"></div>
    
</div>

<script src="/libs/share/js/social-share.min.js"></script>

            <div class="reprint">
                <p>
                    <span class="reprint-tip">转载请注明: </span>
                    <a href="https://zy20081.github.io" class="b-link-green">Zhou•Yong</a>
                    <i class="fa fa-angle-right fa-lg fa-fw text-color"></i>
                    <a href="/2020/10/08/web-zi-dong-hua-ce-shi/" class="b-link-green">web自动化测试</a>
                </p>
            </div>
        </div>
    </div>

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">上一篇</div>
            <div class="card">
                <a href="/2020/11/08/yi-dong-zi-dong-hua/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/21.jpg" class="responsive-img" alt="移动自动化测试">
                        
                        <span class="card-title">移动自动化测试</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary">移动自动化1.java环境2.Android SDK3.模拟器/真机4.常用操作
java安装jdk-8u151-windows-x64.exe
配置环境变量
    自定义变量JAVA_HOME=C:\Program Files\Java</div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="fa fa-clock-o fa-fw icon-date"></i>2020-11-08
                        </span>
                        <span class="publish-author">
                            
                            <i class="fa fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/测试/" class="post-category" target="_blank">
                                    测试
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/移动自动化测试/" target="_blank">
                        <span class="chip bg-color">移动自动化测试</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">下一篇</div>
            <div class="card">
                <a href="/2020/09/08/app-shou-gong-ce-shi/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/21.jpg" class="responsive-img" alt="APP手工测试">
                        
                        <span class="card-title">APP手工测试</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary">测试阶段 APP手工测试，流程和测试用例都跟web手工测试一样的，可以见本站的web手工测试帖子，这里主要写不同地方
APP测试分类1.业务功能测试
2.APP专项测试
  - 兼容性测试
  - 安装、卸载、升级测试
  - 交叉事件测试</div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="fa fa-clock-o fa-fw icon-date"></i>2020-09-08
                            </span>
                        <span class="publish-author">
                            
                            <i class="fa fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/测试/" class="post-category" target="_blank">
                                    测试
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/APP手工测试/" target="_blank">
                        <span class="chip bg-color">APP手工测试</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>
</div>


    </div>
    <div class="col l3 hide-on-med-and-down">
        <div class="toc-widget">
            <div class="toc-title">目录</div>
            <div id="toc-content">

            </div>
        </div>
    </div>
</div>

<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });
    });
</script>
    

</main>


<footer class="page-footer bg-color">
    <div class="container row center-align">
        <div class="col s12 m8 l8 copy-right">
            本站由ZhouYong 技术分享，心得分享.
        </div>
        <div class="col s12 m4 l4 social-link"><a href="#!" class="tooltipped" data-tooltip="邮件联系我: zy20081@126.com" data-position="top" data-delay="50">
    <i class="fa fa-envelope-open"></i>
</a>
<a href="#!" class="tooltipped" data-tooltip="QQ联系我: 314153271" data-position="top" data-delay="50">
    <i class="fa fa-qq"></i>
</a>

<a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
    <i class="fa fa-rss"></i>
</a>
</div>
    </div>
</footer>

<div class="progress-bar"></div>


<!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title">搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字" class="search-input" autofocus>
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script src="/js/search.js"></script>
<script type="text/javascript">
    searchFunc("/" + "search.xml", 'searchInput', 'searchResult');
</script>
<!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fa fa-angle-up"></i>
    </a>
</div>


<script src="/libs/materialize/js/materialize.min.js"></script>
<script src="/libs/masonry/masonry.pkgd.min.js"></script>
<script src="/libs/aos/aos.js"></script>
<script src="/libs/scrollprogress/scrollProgress.min.js"></script>
<script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>

<script src="/libs/others/clicklove.js"></script>

<script src="/js/matery.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->


</body>
</html>